home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / trans / qa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-12  |  29.0 KB  |  928 lines

  1. /*----------------------------------------------------------------------------*\
  2. |   qa.c - A template for a Windows application                                |
  3. |                                                                              |
  4. |   History:                                                                   |
  5. |       01/01/88 toddla     Created                                            |
  6. |                                                                              |
  7. \*----------------------------------------------------------------------------*/
  8.  
  9. #include <windows.h>
  10. #include <windowsx.h>
  11. #include <commdlg.h>
  12. #include <mmsystem.h>   // for timeGetTime()
  13. #include <stdlib.h>     // for rand()
  14. #include "qa.h"
  15. #include "dib.h"
  16. #include "tblt.h"
  17. #include "trle.h"
  18.  
  19. #ifdef WIN32
  20.     //
  21.     // unless you have Win32s 1.1 timeGetTime() does not work
  22.     //
  23.     #define timeGetTime()   GetTickCount()
  24. #endif
  25.  
  26. /*----------------------------------------------------------------------------*\
  27. |                                                                              |
  28. |   g l o b a l   v a r i a b l e s                                            |
  29. |                                                                              |
  30. \*----------------------------------------------------------------------------*/
  31. static  char    szAppName[]="Transparent App";
  32. static  char    szAppFilter[]="Bitmaps\0*.bmp;*.dib\0All Files\0*.*\0";
  33.  
  34. static  HINSTANCE hInstApp;
  35. static  HWND      hwndApp;
  36. static  HACCEL    hAccelApp;
  37. static    HPALETTE  hpalApp;
  38. static    BOOL      fAppActive;
  39.  
  40. #ifdef WIN32
  41.     #define _export
  42. #endif
  43.  
  44. static UINT    DibUsage;
  45. static LPBITMAPINFOHEADER lpbiApp;
  46. static LPBITMAPINFOHEADER lpbiRle;
  47. static HBITMAP hbmApp;
  48. static HBITMAP hbmMaskC;
  49. static HBITMAP hbmMaskM;
  50. static HBITMAP hbmB;
  51. static HDC     hdcApp;
  52. static HDC     hdcMaskC;
  53. static HDC     hdcMaskM;
  54. static HDC     hdcB;
  55.  
  56. typedef void (*PDrawSprite)(HDC hdc, int x, int y);
  57.  
  58. void DrawSpriteMaskM(HDC hdc, int x, int y);
  59. void DrawSpriteMaskC(HDC hdc, int x, int y);
  60. void DrawSpriteMaskT(HDC hdc, int x, int y);
  61. void DrawSpriteMask(HDC hdc, int x, int y);
  62. void DrawSpriteRLE(HDC hdc, int x, int y);
  63.  
  64. static PDrawSprite  DrawSprite;
  65. static UINT         RandomSeed;
  66. static BOOL         gfClipping = FALSE;
  67. static BOOL         gfOffscreen = FALSE;
  68.  
  69. BOOL IsWin32s()
  70. {
  71.     return LOBYTE(GetVersion()) == 3 && (GetVersion() & 0x80000000l);
  72. }
  73.  
  74. BOOL InitMaskBlt()  {return !IsWin32s();}
  75.  
  76. //
  77. //  table of posible sprite drawers.
  78. //
  79. struct {
  80.     PDrawSprite Draw;
  81.     BOOL (*Init)(void);
  82.     char *      szName;
  83. }   aDraw[] = {
  84.         DrawSpriteMaskC,NULL,       "Color Mask",
  85.         DrawSpriteMaskM,NULL,       "Mono Mask",
  86.         DrawSpriteMaskT,NULL,       "True Mask",
  87.         DrawSpriteRLE,  NULL,       "RLE Sprite",
  88. #ifdef WIN32
  89.         DrawSpriteMask, InitMaskBlt,"MaskBlt",
  90. #endif
  91. };
  92.  
  93. #define NUM_DRAW    (sizeof(aDraw) / sizeof(aDraw[0]))
  94.  
  95. /*----------------------------------------------------------------------------*\
  96. \*----------------------------------------------------------------------------*/
  97. void SetDraw(int i)
  98. {
  99.     char ach[128];
  100.  
  101.     if (aDraw[i].Draw == NULL)
  102.         return;
  103.  
  104.     DrawSprite = aDraw[i].Draw;
  105.     wsprintf(ach, "%s - %s", (LPSTR)szAppName, (LPSTR)aDraw[i].szName);
  106.     SetWindowText(hwndApp, ach);
  107. }
  108.  
  109. /*----------------------------------------------------------------------------*\
  110. |                                                                              |
  111. |   f u n c t i o n   d e f i n i t i o n s                                    |
  112. |                                                                              |
  113. \*----------------------------------------------------------------------------*/
  114.  
  115. LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  116. int  ErrMsg (LPSTR sz,...);
  117. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
  118.  
  119. void AppExit(void);
  120. BOOL AppIdle(void);
  121. void AppOpenFile(HWND hwnd, LPSTR szFileName);
  122.  
  123. /*----------------------------------------------------------------------------*\
  124. |   AppAbout( hDlg, uiMessage, wParam, lParam )                                |
  125. |                                                                              |
  126. |   Description:                                                               |
  127. |       This function handles messages belonging to the "About" dialog box.    |
  128. |       The only message that it looks for is WM_COMMAND, indicating the use   |
  129. |       has pressed the "OK" button.  When this happens, it takes down         |
  130. |       the dialog box.                                                        |
  131. |                                                                              |
  132. |   Arguments:                                                                 |
  133. |       hDlg            window handle of about dialog window                   |
  134. |       uiMessage       message number                                         |
  135. |       wParam          message-dependent                                      |
  136. |       lParam          message-dependent                                      |
  137. |                                                                              |
  138. |   Returns:                                                                   |
  139. |       TRUE if message has been processed, else FALSE                         |
  140. |                                                                              |
  141. \*----------------------------------------------------------------------------*/
  142. BOOL FAR PASCAL _export AppAbout(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  143. {
  144.     switch (msg)
  145.     {
  146.         case WM_COMMAND:
  147.         if (LOWORD(wParam) == IDOK)
  148.             {
  149.                 EndDialog(hwnd,TRUE);
  150.             }
  151.             break;
  152.  
  153.         case WM_INITDIALOG:
  154.             return TRUE;
  155.     }
  156.     return FALSE;
  157. }
  158.  
  159. /*----------------------------------------------------------------------------*\
  160. |   AppInit( hInst, hPrev)                                                     |
  161. |                                                                              |
  162. |   Description:                                                               |
  163. |       This is called when the application is first loaded into               |
  164. |       memory.  It performs all initialization that doesn't need to be done   |
  165. |       once per instance.                                                     |
  166. |                                                                              |
  167. |   Arguments:                                                                 |
  168. |       hInstance       instance handle of current instance                    |
  169. |       hPrev           instance handle of previous instance                   |
  170. |                                                                              |
  171. |   Returns:                                                                   |
  172. |       TRUE if successful, FALSE if not                                       |
  173. |                                                                              |
  174. \*----------------------------------------------------------------------------*/
  175. BOOL AppInit(HINSTANCE hInst,HINSTANCE hPrev,int sw,LPSTR szCmdLine)
  176. {
  177.     WNDCLASS cls;
  178.     int      dx,dy;
  179.     int      i;
  180.  
  181.     /* Save instance handle for DialogBoxs */
  182.     hInstApp = hInst;
  183.  
  184.     hAccelApp = LoadAccelerators(hInst, "AppAccel");
  185.  
  186.     if (!hPrev)
  187.     {
  188.         /*
  189.          *  Register a class for the main application window
  190.          */
  191.         cls.hCursor        = LoadCursor(NULL,IDC_ARROW);
  192.         cls.hIcon          = LoadIcon(hInst,"AppIcon");
  193.         cls.lpszMenuName   = "AppMenu";
  194.         cls.lpszClassName  = szAppName;
  195.         cls.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  196.         cls.hInstance      = hInst;
  197.         cls.style          = CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  198.         cls.lpfnWndProc    = (WNDPROC)AppWndProc;
  199.         cls.cbWndExtra     = 0;
  200.         cls.cbClsExtra     = 0;
  201.  
  202.         if (!RegisterClass(&cls))
  203.             return FALSE;
  204.     }
  205.  
  206.     dx = GetSystemMetrics (SM_CXSCREEN) / 2;
  207.     dy = GetSystemMetrics (SM_CYSCREEN) / 2;
  208.  
  209.     hwndApp = CreateWindow (szAppName,    // Class name
  210.                             szAppName,              // Caption
  211.                             WS_OVERLAPPEDWINDOW,    // Style bits
  212.                             CW_USEDEFAULT, 0,       // Position
  213.                 dx,dy,            // Size
  214.                             (HWND)NULL,             // Parent window (no parent)
  215.                             (HMENU)NULL,            // use class menu
  216.                             hInst,                  // handle to window instance
  217.                             (LPSTR)NULL             // no params to pass on
  218.                            );
  219.     ShowWindow(hwndApp,sw);
  220.  
  221.     if (*szCmdLine)
  222.         AppOpenFile(hwndApp, szCmdLine);
  223.     else
  224.         AppOpenFile(hwndApp, "Herman");
  225.  
  226.     RandomSeed = (UINT)timeGetTime();
  227.     srand(RandomSeed);
  228.  
  229.     //
  230.     // init every thing.
  231.     //                   
  232.     for (i=0; i<NUM_DRAW; i++)
  233.     {
  234.         if (aDraw[i].Init && !aDraw[i].Init())
  235.             aDraw[i].Draw = NULL;
  236.     }
  237.                
  238.     //
  239.     // build the draw menu.
  240.     //
  241.     HMENU hmenu = GetSubMenu(GetMenu(hwndApp), 1);
  242.     DeleteMenu(hmenu, MENU_DRAW, MF_BYCOMMAND);
  243.  
  244.     for (i=0; i<NUM_DRAW; i++)
  245.     {
  246.         AppendMenu(hmenu, 0, MENU_DRAW+i, aDraw[i].szName);
  247.     }
  248.  
  249.     AppendMenu(hmenu, MF_SEPARATOR, -1, NULL);
  250.     AppendMenu(hmenu, 0, MENU_CLIP, "Clipping");
  251.     AppendMenu(hmenu, 0, MENU_OFFSCREEN, "Offscreen");
  252.  
  253.     // pick a default.
  254.     SetDraw(0);
  255.  
  256.     return TRUE;
  257. }
  258.  
  259.  
  260. /*----------------------------------------------------------------------------*\
  261. |   AppExit()                                       |
  262. |                                                                              |
  263. |   Description:                                                               |
  264. |    app is just about to exit, cleanup                       |
  265. |                                                                              |
  266. \*----------------------------------------------------------------------------*/
  267. void AppExit()
  268. {
  269.     AppOpenFile(hwndApp, NULL);
  270. }
  271.  
  272. /*----------------------------------------------------------------------------*\
  273. \*----------------------------------------------------------------------------*/
  274.  
  275. #define RandRGB() RGB(rand() % 256, rand() % 256, rand() % 256)
  276. #define RandPT(pt, rc) ((pt).x = rc.left + (rand() % (rc.right-rc.left))), ((pt).y = rc.top + (rand() % (rc.bottom-rc.top)))
  277.  
  278. RECT    rcSprite;
  279.  
  280. void DoSprite(HDC hdc=NULL, LONG l=0)
  281. {
  282.     POINT pt;
  283.     BOOL fGetDC;
  284.  
  285.     if (fGetDC = (hdc == NULL))
  286.     {
  287.         hdc = GetDC(hwndApp);
  288.  
  289.         SelectPalette(hdc, hpalApp, FALSE);
  290.         RealizePalette(hdc);
  291.  
  292.         if (gfOffscreen)
  293.         {
  294.             SelectPalette(hdcB, hpalApp, FALSE);
  295.             RealizePalette(hdcB);
  296.         }
  297.     }    
  298.  
  299.     if (l == 0)
  300.         RandPT(pt, rcSprite);
  301.     else
  302.         pt.x = LOWORD(l), pt.y = HIWORD(l);
  303.  
  304.     if (gfOffscreen)
  305.     {
  306.         BitBlt(hdcB, 0, 0, DibWidth(lpbiApp), DibHeight(lpbiApp), hdc, pt.x, pt.y, SRCCOPY);
  307.         DrawSprite(hdcB, 0, 0);
  308.         BitBlt(hdc, pt.x, pt.y, DibWidth(lpbiApp), DibHeight(lpbiApp), hdcB, 0, 0, SRCCOPY);
  309.     }
  310.     else
  311.     {
  312.         DrawSprite(hdc, pt.x, pt.y);
  313.     }
  314.  
  315.     if (fGetDC)
  316.         ReleaseDC(hwndApp, hdc);
  317.  
  318.     if (fGetDC && gfOffscreen)
  319.         SelectPalette(hdcB, (HPALETTE)GetStockObject(DEFAULT_PALETTE), FALSE);
  320. }
  321.  
  322. /*----------------------------------------------------------------------------*\
  323. |   TimeIt()                                                                 |
  324. \*----------------------------------------------------------------------------*/
  325.  
  326. #define N 100
  327.  
  328. #define FPS(time,n) \
  329.             time ? (1000l * n / time) : 0, \
  330.             time ? (1000000l * n / time) % 1000: 0
  331.  
  332. static char achMsg[4000];
  333.  
  334. void TimeIt()
  335. {
  336.     HDC hdc;
  337.     LONG time;
  338.     int i,n;
  339.     char *pch;
  340.     HCURSOR hcur;
  341.  
  342.     InvalidateRect(hwndApp, NULL, TRUE);
  343.     UpdateWindow(hwndApp);
  344.  
  345.     hdc = GetDC(hwndApp);
  346.  
  347.     SelectPalette(hdc, hpalApp, FALSE);
  348.     RealizePalette(hdc);
  349.  
  350.     if (gfOffscreen)
  351.     {
  352.         SelectPalette(hdcB, hpalApp, FALSE);
  353.         RealizePalette(hdcB);
  354.     }
  355.  
  356.     SetStretchBltMode(hdc, COLORONCOLOR);
  357.  
  358.     hcur = SetCursor(NULL);
  359.  
  360.     pch = achMsg;
  361.  
  362.     for (n=0; n<NUM_DRAW; n++)
  363.     {
  364.         if (aDraw[n].Draw == NULL)
  365.             continue;
  366.  
  367.         SetDraw(n);
  368.         srand(RandomSeed);
  369.  
  370.         time = timeGetTime();
  371.  
  372.         for (i=0; i<N; i++)
  373.         DoSprite(hdc);
  374.  
  375.     time = timeGetTime() - time;
  376.  
  377.         pch += wsprintf(pch, "%-20s\t%ld.%03ld fps\n", (LPSTR)aDraw[n].szName, FPS(time,N));
  378.     }
  379.  
  380.     SetCursor(hcur);
  381.     ReleaseDC(hwndApp, hdc);
  382.  
  383.     SetDraw(0);
  384.     MessageBox(hwndApp,achMsg,szAppName,MB_OK|MB_ICONINFORMATION|MB_TASKMODAL);
  385. }
  386.  
  387. /*----------------------------------------------------------------------------*\
  388. |   WinMain( hInst, hPrev, lpszCmdLine, cmdShow )                              |
  389. |                                                                              |
  390. |   Description:                                                               |
  391. |       The main procedure for the App.  After initializing, it just goes      |
  392. |       into a message-processing loop until it gets a WM_QUIT message         |
  393. |       (meaning the app was closed).                                          |
  394. |                                                                              |
  395. |   Arguments:                                                                 |
  396. |       hInst           instance handle of this instance of the app            |
  397. |       hPrev           instance handle of previous instance, NULL if first    |
  398. |       szCmdLine       ->null-terminated command line                         |
  399. |       cmdShow         specifies how the window is initially displayed        |
  400. |                                                                              |
  401. |   Returns:                                                                   |
  402. |       The exit code as specified in the WM_QUIT message.                     |
  403. |                                                                              |
  404. \*----------------------------------------------------------------------------*/
  405. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
  406. {
  407.     MSG     msg;
  408.  
  409.     /* Call initialization procedure */
  410.     if (!AppInit(hInst,hPrev,sw,szCmdLine))
  411.     return FALSE;
  412.  
  413.     /*
  414.      * Polling messages from event queue
  415.      */
  416.     for (;;)
  417.     {
  418.         if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
  419.         {
  420.             if (msg.message == WM_QUIT)
  421.                 break;
  422.  
  423.         if (hAccelApp && TranslateAccelerator(hwndApp, hAccelApp, &msg))
  424.         continue;
  425.  
  426.             TranslateMessage(&msg);
  427.             DispatchMessage(&msg);
  428.         }
  429.         else
  430.     {
  431.         if (AppIdle())
  432.                 WaitMessage();
  433.         }
  434.     }
  435.  
  436.     AppExit();
  437.     return msg.wParam;
  438. }
  439.  
  440. /*----------------------------------------------------------------------------*\
  441. |   AppIdle()                                       |
  442. |                                                                              |
  443. |   Description:                                                               |
  444. |    place to do idle time stuff.                           |
  445. |                                                                              |
  446. |   Returns:                                       |
  447. |    RETURN TRUE IF YOU HAVE NOTHING TO DO OTHERWISE YOUR APP WILL BE A     |
  448. |    CPU PIG!                                   |
  449. \*----------------------------------------------------------------------------*/
  450. BOOL AppIdle()
  451. {
  452.     if (fAppActive)
  453.     {
  454.         //
  455.         // dont draw while tracking.
  456.         //
  457.         if (GetCapture() == hwndApp)
  458.             return TRUE;
  459.  
  460.     //
  461.         // we are the foreground app, so draw randomly
  462.         //
  463.         if (lpbiApp && DrawSprite)
  464.         {
  465.             DoSprite();
  466.             return FALSE;
  467.         }
  468.  
  469.     return TRUE;        // nothing to do.
  470.     }
  471.     else
  472.     {
  473.     //
  474.     // we are a background app.
  475.     //
  476.     return TRUE;        // nothing to do.
  477.     }
  478. }
  479.  
  480. /*----------------------------------------------------------------------------*\
  481. |   AppOpenFile()                                   |
  482. |                                                                              |
  483. |   Description:                                                               |
  484. |    open a file stupid                               |
  485. |                                                                              |
  486. \*----------------------------------------------------------------------------*/
  487. void AppOpenFile(HWND hwnd, LPSTR szFileName)
  488. {
  489.     HDC hdc;
  490.  
  491.     if (hpalApp)
  492.         DeleteObject(hpalApp);
  493.  
  494.     if (hdcApp)
  495.     DeleteObject(hdcApp);
  496.  
  497.     if (hdcMaskC)
  498.         DeleteObject(hdcMaskC);
  499.  
  500.     if (hdcB)
  501.         DeleteObject(hdcB);
  502.  
  503.     if (hdcMaskM)
  504.         DeleteObject(hdcMaskM);
  505.  
  506.     if (hbmApp)
  507.         DeleteObject(hbmApp);
  508.  
  509.     if (hbmMaskC)
  510.         DeleteObject(hbmMaskC);
  511.         
  512.     if (hbmB)
  513.         DeleteObject(hbmB);
  514.  
  515.     if (hbmMaskM)
  516.         DeleteObject(hbmMaskM);
  517.  
  518.     if (lpbiApp)
  519.         DibFree(lpbiApp);
  520.  
  521.     if (lpbiRle)
  522.         DibFree(lpbiRle);
  523.  
  524.     hpalApp  = NULL;
  525.     lpbiApp  = NULL;
  526.     hbmApp   = NULL;
  527.     hbmMaskC = NULL;
  528.     hbmMaskM = NULL;
  529.     hdcApp   = NULL;
  530.     hdcMaskC = NULL;
  531.     hdcMaskM = NULL;
  532.  
  533.     if (szFileName == NULL)
  534.         return;
  535.  
  536.     lpbiApp = DibOpenFile(szFileName);
  537.  
  538.     if (lpbiApp == NULL)
  539.     {
  540.         ErrMsg("Cant open %s", szFileName);
  541.         return;
  542.     }
  543.  
  544.     //
  545.     // get the palette
  546.     //
  547.     hpalApp = DibCreatePalette(lpbiApp);
  548.  
  549.     //
  550.     //  make this a identity palette for fast drawing.
  551.     //
  552.     MakeIdentityPalette(hpalApp);
  553.     DibMapToPalette(lpbiApp, hpalApp);
  554.  
  555.     //
  556.     // convert to a bitmap
  557.     //
  558.     hbmApp = BitmapFromDib(lpbiApp, hpalApp, DIB_RGB_COLORS);
  559.  
  560.     //
  561.     // now make a trans mask.
  562.     //
  563.     hbmMaskM = MakeTransMask(hbmApp, hpalApp, -1);     // mono mask
  564.  
  565.     //
  566.     // make a transparent RLE
  567.     //
  568.     lpbiRle = MakeRleDib(lpbiApp, -1);
  569.  
  570.     hdc = GetDC(NULL);
  571.  
  572.     //
  573.     // we will use DIB_PAL_COLORS to draw dibs on a palette device.
  574.     //
  575.     if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
  576.     {
  577.         DibUsage = DIB_PAL_COLORS;
  578.         DibSetUsage(lpbiRle, hpalApp, DIB_PAL_COLORS);
  579.     }
  580.  
  581.     //
  582.     // make memory DCs for easy access.
  583.     //
  584.     hdcApp = CreateCompatibleDC(hdc);
  585.     hdcMaskM = CreateCompatibleDC(hdc);
  586.     hdcMaskC = CreateCompatibleDC(hdc);
  587.     hdcB = CreateCompatibleDC(hdc); 
  588.     hbmB = CreateCompatibleBitmap(hdc, DibWidth(lpbiApp), DibHeight(lpbiApp));
  589.     hbmMaskC = CreateCompatibleBitmap(hdc, DibWidth(lpbiApp), DibHeight(lpbiApp));
  590.  
  591.     ReleaseDC(NULL, hdc);
  592.  
  593.     SelectObject(hdcApp, hbmApp);
  594.     SelectObject(hdcB, hbmB);
  595.     SelectObject(hdcMaskM, hbmMaskM);
  596.     SelectObject(hdcMaskC, hbmMaskC);
  597.  
  598.     // convert mask to color.
  599.     BitBlt(hdcMaskC, 0, 0, DibWidth(lpbiApp), DibHeight(lpbiApp), hdcMaskM, 0, 0, SRCCOPY);
  600.  
  601.     SendMessage(hwndApp, WM_SIZE, 0, 0);
  602. }
  603.  
  604. /*----------------------------------------------------------------------------*\
  605. |   AppPaint(hwnd, hdc)                                                        |
  606. |                                                                              |
  607. |   Description:                                                               |
  608. |       The paint function.  Right now this does nothing.                      |
  609. |                                                                              |
  610. |   Arguments:                                                                 |
  611. |       hwnd             window painting into                                  |
  612. |       hdc              display context to paint to                           |
  613. |                                                                              |
  614. |   Returns:                                                                   |
  615. |       nothing                                                                |
  616. |                                                                              |
  617. \*----------------------------------------------------------------------------*/
  618. AppPaint (HWND hwnd, HDC hdc)
  619. {
  620.     return TRUE;
  621. }
  622.  
  623. /*----------------------------------------------------------------------------*\
  624. |   AppWndProc( hwnd, uiMessage, wParam, lParam )                              |
  625. |                                                                              |
  626. |   Description:                                                               |
  627. |       The window proc for the app's main (tiled) window.  This processes all |
  628. |       of the parent window's messages.                                       |
  629. |                                                                              |
  630. \*----------------------------------------------------------------------------*/
  631. LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  632. {
  633.     PAINTSTRUCT ps;
  634.     HDC hdc;
  635.     BOOL f;
  636.     int i;
  637.  
  638.     switch (msg)
  639.     {
  640.         case WM_CREATE:
  641.         break;
  642.  
  643.         case WM_ACTIVATEAPP:
  644.             fAppActive = (BOOL)wParam;
  645.  
  646.             //
  647.             //  on Win32/NT or Win32c (not Win32s) we can use DIB_PAL_INDICES
  648.             //  when in the foreground because we converted our DIB color
  649.             //  table to match the system palette 1:1 when we loaded it.
  650.             //  and we are using a "identity" palette.
  651.             //
  652. #ifdef WIN32
  653.             if (!IsWin32s() && DibUsage != DIB_RGB_COLORS)
  654.                 DibUsage = fAppActive ? DIB_PAL_INDICES : DIB_PAL_COLORS;
  655. #endif
  656.         break;
  657.  
  658.         case WM_TIMER:
  659.             break;
  660.  
  661.         case WM_ERASEBKGND:
  662.             break;
  663.  
  664.         case WM_INITMENU:
  665.             for (i=0; i<NUM_DRAW; i++)
  666.             {
  667.                 EnableMenuItem((HMENU)wParam, MENU_DRAW + i, aDraw[i].Draw ? MF_ENABLED : MF_GRAYED);
  668.                 CheckMenuItem((HMENU)wParam, MENU_DRAW + i, DrawSprite == aDraw[i].Draw ? MF_CHECKED : MF_UNCHECKED);
  669.             }
  670.  
  671.             CheckMenuItem((HMENU)wParam, MENU_CLIP, gfClipping ? MF_CHECKED : MF_UNCHECKED);
  672.             CheckMenuItem((HMENU)wParam, MENU_OFFSCREEN, gfOffscreen ? MF_CHECKED : MF_UNCHECKED);
  673.         break;
  674.  
  675.         case WM_COMMAND:
  676.             return AppCommand(hwnd,msg,wParam,lParam);
  677.  
  678.     case WM_DESTROY:
  679.         hAccelApp = NULL;
  680.             PostQuitMessage(0);
  681.             break;
  682.  
  683.         case WM_SIZE:
  684.             GetClientRect(hwnd, &rcSprite);
  685.  
  686.             if (lpbiApp == NULL)
  687.                 return 0L;
  688.  
  689.             if (!gfClipping)
  690.             {
  691.                 if ((int)DibWidth(lpbiApp) < rcSprite.right)
  692.                     rcSprite.right  -= DibWidth(lpbiApp);
  693.  
  694.                 if ((int)DibHeight(lpbiApp) < rcSprite.bottom)
  695.                     rcSprite.bottom -= DibHeight(lpbiApp);
  696.             }
  697.             else
  698.             {
  699.                 rcSprite.left   -= DibWidth(lpbiApp);
  700.                 rcSprite.right  += DibWidth(lpbiApp);
  701.                 rcSprite.top    -= DibHeight(lpbiApp);
  702.                 rcSprite.bottom += DibHeight(lpbiApp);
  703.             }
  704.             break;
  705.  
  706.         case WM_CLOSE:
  707.         break;
  708.  
  709.         case WM_PALETTECHANGED:
  710.         if ((HWND)wParam == hwnd)
  711.         break;
  712.  
  713.         // fall through to WM_QUERYNEWPALETTE
  714.  
  715.     case WM_QUERYNEWPALETTE:
  716.         hdc = GetDC(hwnd);
  717.  
  718.         if (hpalApp)
  719.         SelectPalette(hdc, hpalApp, FALSE);
  720.  
  721.         f = RealizePalette(hdc);
  722.         ReleaseDC(hwnd,hdc);
  723.  
  724.         if (f)
  725.         InvalidateRect(hwnd,NULL,TRUE);
  726.  
  727.         return f;
  728.  
  729.         case WM_PAINT:
  730.         hdc = BeginPaint(hwnd,&ps);
  731.         AppPaint (hwnd,hdc);
  732.             EndPaint(hwnd,&ps);
  733.             return 0L;
  734.  
  735.         case WM_MOUSEMOVE:
  736.             if ((UINT)wParam & MK_LBUTTON)
  737.                 DoSprite(NULL, (LONG)lParam);
  738.             break;
  739.  
  740.         case WM_LBUTTONDOWN:
  741.             SetCapture(hwnd);
  742.             DoSprite(NULL, (LONG)lParam);
  743.             break;
  744.  
  745.         case WM_LBUTTONUP:
  746.             ReleaseCapture();
  747.             break;
  748.     }
  749.     return DefWindowProc(hwnd,msg,wParam,lParam);
  750. }
  751.  
  752. /*----------------------------------------------------------------------------*\
  753. |   AppCommand(hwnd, msg, wParam, lParam )                       |
  754. |                                                                              |
  755. |   Description:                                                               |
  756. |    handles WM_COMMAND messages for the main window (hwndApp)           |
  757. |       of the parent window's messages.                                       |
  758. |                                                                              |
  759. \*----------------------------------------------------------------------------*/
  760. LONG AppCommand (HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
  761. {
  762.     static char achFileName[128];
  763.     static OPENFILENAME ofn;
  764.     int i;
  765.  
  766.     switch(LOWORD(wParam))
  767.     {
  768.         case MENU_ABOUT:
  769.         DialogBox(hInstApp,"AppAbout",hwnd,AppAbout);
  770.             break;
  771.  
  772.     case MENU_OPEN:
  773.             achFileName[0] = 0;
  774.  
  775.             /* prompt user for file to open */
  776.             ofn.lStructSize = sizeof(OPENFILENAME);
  777.             ofn.hwndOwner = hwnd;
  778.             ofn.hInstance = NULL;
  779.         ofn.lpstrFilter = szAppFilter;
  780.             ofn.lpstrCustomFilter = NULL;
  781.             ofn.nMaxCustFilter = 0;
  782.             ofn.nFilterIndex = 0;
  783.             ofn.lpstrFile = achFileName;
  784.         ofn.nMaxFile = sizeof(achFileName);
  785.             ofn.lpstrFileTitle = NULL;
  786.             ofn.nMaxFileTitle = 0;
  787.             ofn.lpstrInitialDir = NULL;
  788.         ofn.lpstrTitle = NULL;
  789.         ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
  790.             ofn.nFileOffset = 0;
  791.             ofn.nFileExtension = 0;
  792.             ofn.lpstrDefExt = NULL;
  793.             ofn.lCustData = 0;
  794.             ofn.lpfnHook = NULL;
  795.             ofn.lpTemplateName = NULL;
  796.  
  797.             if (GetOpenFileName(&ofn))
  798.             {
  799.         AppOpenFile(hwnd,achFileName);
  800.             }
  801.  
  802.             break;
  803.  
  804.         case MENU_EXIT:
  805.             PostMessage(hwnd,WM_CLOSE,0,0L);
  806.             break;
  807.  
  808.         case MENU_TIME:
  809.             TimeIt();
  810.             break;
  811.  
  812.         case MENU_CLIP:
  813.             gfClipping = !gfClipping;
  814.             PostMessage(hwnd, WM_SIZE, 0, 0);
  815.             break;
  816.  
  817.         case MENU_OFFSCREEN:
  818.             gfOffscreen = !gfOffscreen;
  819.             break;
  820.  
  821.     default:
  822.         i = (int)LOWORD(wParam) - MENU_DRAW;
  823.         
  824.             if (i >= 0 && i < NUM_DRAW && aDraw[i].Draw)
  825.                 SetDraw(i);
  826.             
  827.             InvalidateRect(hwnd, NULL, TRUE);
  828.             break;
  829.     }
  830.     return 0L;
  831. }
  832.  
  833. void DrawSpriteMaskM(HDC hdc, int x, int y)
  834. {
  835.     TransMaskBlt(hdc, x, y, DibWidth(lpbiApp), DibHeight(lpbiApp),
  836.         hdcApp, hdcMaskM, 0, 0);
  837. }
  838.  
  839. void DrawSpriteMaskT(HDC hdc, int x, int y)
  840. {
  841.     TrueMaskBlt(hdc, x, y, DibWidth(lpbiApp), DibHeight(lpbiApp),
  842.         hdcApp, hdcMaskM, 0, 0);
  843. }
  844.  
  845. void DrawSpriteMaskC(HDC hdc, int x, int y)
  846. {
  847.     TransMaskBlt(hdc, x, y, DibWidth(lpbiApp), DibHeight(lpbiApp),
  848.         hdcApp, hdcMaskC, 0, 0);
  849. }
  850.  
  851. void DrawSpriteRLE(HDC hdc, int x, int y)
  852. {
  853.     DibDraw(hdc,x,y,-1,-1,lpbiRle,0,0,-1,-1,SRCCOPY,DibUsage);
  854. }
  855.  
  856. #ifdef WIN32
  857. void DrawSpriteMask(HDC hdc, int x, int y)
  858. {
  859.     MaskBlt(hdc, x, y, DibWidth(lpbiApp), DibHeight(lpbiApp),
  860.             hdcApp, 0, 0, hbmMaskM, 0, 0, 0xCCAA0000);
  861. }
  862. #endif
  863.  
  864. /*----------------------------------------------------------------------------*\
  865. |   ErrMsg - Opens a Message box with a error message in it.  The user can     |
  866. |            select the OK button to continue                                  |
  867. \*----------------------------------------------------------------------------*/
  868. int ErrMsg (LPSTR sz,...)
  869. {
  870.     static char ach[128];
  871.  
  872.     wvsprintf (ach,sz,(LPSTR)(&sz+1));   /* Format the string */
  873.     MessageBox(hwndApp,ach,szAppName,MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL);
  874.     return FALSE;
  875. }
  876.  
  877. /*****************************************************************************
  878.  *
  879.  * dprintf() is called by the DPF macro if DEBUG is defined at compile time.
  880.  *
  881.  * The messages will be send to COM1: like any debug message. To
  882.  * enable debug output, add the following to WIN.INI :
  883.  *
  884.  * [debug]
  885.  * QA=1
  886.  *
  887.  ****************************************************************************/
  888.  
  889. #ifdef DEBUG
  890.  
  891. #define MODNAME "QA"
  892.  
  893. #ifndef WIN32
  894.     #define lstrcatA lstrcat
  895.     #define lstrcpyA lstrcpy
  896.     #define lstrlenA lstrlen
  897.     #define wvsprintfA      wvsprintf
  898.     #define GetProfileIntA  GetProfileInt
  899.     #define OutputDebugStringA OutputDebugString
  900. #endif
  901.  
  902. #define _WINDLL
  903. #include <stdarg.h>
  904.  
  905. void FAR CDECL dprintf(LPSTR szFormat, ...)
  906. {
  907.     char ach[128];
  908.     va_list va;
  909.  
  910.     static BOOL fDebug = -1;
  911.  
  912.     if (fDebug == -1)
  913.     fDebug = GetProfileIntA("Debug", MODNAME, TRUE);
  914.  
  915.     if (!fDebug)
  916.         return;
  917.  
  918.     lstrcpyA(ach, MODNAME ": ");
  919.     va_start(va, szFormat);
  920.     wvsprintfA(ach+lstrlenA(ach),szFormat,(LPSTR)va);
  921.     va_end(va);
  922.     lstrcatA(ach, "\r\n");
  923.  
  924.     OutputDebugStringA(ach);
  925. }
  926.  
  927. #endif
  928.